package com.lihonghao.handle;

import cn.hutool.json.JSONUtil;
import com.lihonghao.gateway.DefaultGate;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;


public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    //    private static final AtomicLong ACCESS_COUNT = new AtomicLong(0);
    // 使用Netty推荐的EventExecutorGroup（而非Java原生线程池 ExecutorService）
    private static final EventExecutorGroup BUSINESS_POOL =
            new DefaultEventExecutorGroup(Runtime.getRuntime().availableProcessors() * 2); // 线程数=CPU核心数*2


    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();//读取操作完成之后刷新通道，保证数据能被写入到远程节点。
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
    }


    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
        try {
            //100 Continue
            if (HttpUtil.is100ContinueExpected(req)) {
                ctx.write(new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1,
                        HttpResponseStatus.CONTINUE));
            }
            // 执行业务逻辑（异步非阻塞）
            handleBusiness(req, ctx);

            // 统计访问次数（原子操作）
//            long count = ACCESS_COUNT.incrementAndGet();
            //System.out.println("访问次数" + count);
        } catch (Exception e) {
            e.printStackTrace();
            ctx.writeAndFlush(createErrorResponse()).addListener(ChannelFutureListener.CLOSE);// 将html write到客户端
            }
    }

    //ctx.writeAndFlush 结束所有的handler响应直接返回
    //ctx.chain().writeAndFlush 结束当前的handler响应，向下传递

    // 业务逻辑处理（单独方法，便于复用和测试）
    private void handleBusiness(FullHttpRequest req, ChannelHandlerContext ctx) {
        BUSINESS_POOL.submit(() -> {
            Object result = DefaultGate.action.of(req.uri(), req.method().name().toString());
            ctx.channel().eventLoop().execute(() -> {
                // 创建池化响应（关键优化点）
                FullHttpResponse response = createPooledResponse(JSONUtil.toJsonStr(result)); // 构造响应
                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
            });
        });
    }

    private static FullHttpResponse createPooledResponse(String content) {
        // 使用池化缓冲区（减少内存分配开销）
        ByteBuf buf = Unpooled.wrappedBuffer(content.getBytes(StandardCharsets.UTF_8));
        // 或使用PooledByteBuf：
//         ByteBuf buf = ctx.alloc().buffer().writeBytes(content.getBytes());
        //创建http响应
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                buf);
        //设置头信息
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
        return response;
    }

    private static FullHttpResponse errorResponse;

    static {
        HashMap errorData = new HashMap();
        errorData.put("error", "Internal Server Error");
        errorData.put("message", "Internal Server Error");
        errorData.put("code", 500);
        ByteBuf buf = Unpooled.wrappedBuffer(JSONUtil.toJsonStr(errorData).getBytes(StandardCharsets.UTF_8));
        errorResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR, buf);
        errorResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
    }

    private static FullHttpResponse createErrorResponse() {
        return errorResponse;
    }
}
